package cn.zzq.aix.nativeinterface.javareflector;

import java.lang.reflect.Array;
import java.lang.reflect.Type;

import com.google.appinventor.components.runtime.util.YailList;

import gnu.lists.FString;

public final class ArrayUtil {
	public static boolean isArray(Object object) {
		return object == null ? false : object.getClass().isArray();
	}

	public static Class<?> buildArrayType(Type componentType, int dimension) {
		int[] dimensions = new int[dimension];
		return Array.newInstance((Class<?>) componentType, dimensions).getClass();
	}

	/**
	 * 根据数组的维度列表创建一个数组实例 创建一个具有指定的元素类型和维度的新数组。dimensionsList为数组维度列表，<br/>
	 * 如数组[[1,2],[3,4],[4,5]]可表示为（长度为2的数组）的数组长度为3，即array[2][3]<br/>
	 * 所以创建一个如上述的多维数组dimensionsList须传入列表(2,3)<br/>
	 * 
	 * @param elementType
	 *            数组元素类型
	 * @param dimensionsList
	 *            数组维度列表
	 * @return
	 */
	public static Object createInstanceByDimensions(Type elementType, YailList dimensionsList) {
		int[] dimensions = (int[]) list2IntArray(dimensionsList);
		return Array.newInstance((Class<?>) elementType, dimensions);
	}

	public static String array2json(Object object) {
		StringBuffer result = new StringBuffer("[");
		if (isArray(object)) {
			for (Object obj : (Object[]) object) {
				result.append(array2json(obj) + ",");
			}
			result.deleteCharAt(result.length() - 1);
			result.append("]");
			return result.toString();
		} else if (object instanceof String) {
			return "\"" + object.toString() + "\"";
		} else if (object == null) {
			return "null";
		} else {
			return object.toString();
		}
	}

	public static YailList array2List(Object array) {
		Object[] objectArray = new Object[Array.getLength(array)];
		for (int i = 0; i < objectArray.length; i++) {
			Object object = Array.get(array, i);
			if (object instanceof Number) {
				objectArray[i] = NumberUtil.JavaNumber2AINumber((Number) object);
			} else {
				objectArray[i] = object;
			}
		}
		return YailList.makeList(objectArray);
	}

	public static Object list2Array(YailList list, Type elementType) {
		if (elementType == boolean.class) {
			return list2BooleanArray(list);
		} else if (elementType == byte.class) {
			return list2ByteArray(list);
		} else if (elementType == char.class) {
			return list2CharArray(list);
		} else if (elementType == double.class) {
			return list2DoubleArray(list);
		} else if (elementType == float.class) {
			return list2FloatArray(list);
		} else if (elementType == int.class) {
			return list2IntArray(list);
		} else if (elementType == long.class) {
			return list2LongArray(list);
		} else if (elementType == short.class) {
			return list2ShortArray(list);
		} else {
			Object array = Array.newInstance((Class<?>) elementType, list.size());
			for (int i = 0; i < list.size(); i++) {
				Array.set(array, i, list.getObject(i));
			}
			return array;
		}
	}

	public static Object list2BooleanArray(YailList list) {
		boolean[] array = new boolean[list.size()];
		for (int i = 0; i < array.length; i++) {
			Object object = list.getObject(i);
			if (object instanceof String || object instanceof FString) {
				array[i] = Boolean.parseBoolean(object.toString());
			} else {
				array[i] = (boolean) object;
			}
		}
		return array;
	}

	public static Object list2ByteArray(YailList list) {
		byte[] array = new byte[list.size()];
		for (int i = 0; i < array.length; i++) {
			array[i] = (byte) Integer.parseInt(list.getObject(i).toString());
		}
		return array;
	}

	public static Object list2CharArray(YailList list) {
		char[] array = new char[list.size()];
		for (int i = 0; i < array.length; i++) {
			Object object = list.getObject(i);
			array[i] = Util.buildChar(object);
		}
		return array;
	}

	public static Object list2FloatArray(YailList list) {
		float[] array = new float[list.size()];
		for (int i = 0; i < array.length; i++) {
			array[i] = Float.parseFloat(list.getObject(i).toString());
		}
		return array;
	}

	public static Object list2DoubleArray(YailList list) {
		double[] array = new double[list.size()];
		for (int i = 0; i < array.length; i++) {
			array[i] = Double.parseDouble(list.getObject(i).toString());
		}
		return array;
	}

	public static Object list2IntArray(YailList list) {
		int[] array = new int[list.size()];
		for (int i = 0; i < array.length; i++) {
			array[i] = (int)Long.parseLong(list.getObject(i).toString());
		}
		return array;
	}

	public static Object list2LongArray(YailList list) {
		long[] array = new long[list.size()];
		for (int i = 0; i < array.length; i++) {
			array[i] = Long.parseLong(list.getObject(i).toString());
		}
		return array;
	}

	public static Object list2ShortArray(YailList list) {
		short[] array = new short[list.size()];
		for (int i = 0; i < array.length; i++) {
			array[i] = (short) Integer.parseInt(list.getObject(i).toString());
		}
		return array;
	}

}
